/* This code is restricted under LGPL license */
using System.Collections.Generic;
using NHibernate.Criterion;

namespace infoMECHANICA.NHibernateORM.CriteriaBuilder
{
    /// <summary>
    /// Interface of properties which are convertible to criterions
    /// </summary>
    /// <typeparam name="T">Base property type</typeparam>
    public interface ICriterionProperty<T>
    {        
        /// <summary>
        /// Create ascending order from property
        /// </summary>
        /// <returns>NHibernate Order object</returns>
        Order AsOrderAsc();

        /// <summary>
        /// 
        /// Create descending order from property
        /// </summary>
        /// <returns>NHibernate Order object</returns>
        Order AsOrderDesc();

        /// <summary>
        /// Get composed value of "Is between..." criterion
        /// </summary>
        /// <param name="beginValue">Begin valueof between range</param>
        /// <param name="endValue">End value of between range</param>
        /// <returns>NHibernate criterion value</returns>
        ICriterion AsBetweenCriterion(T beginValue, T endValue);

        /// <summary>
        /// Get composed value of "Is equal..." criterion
        /// </summary>
        /// <param name="value">Base value</param>
        /// <returns>NHibernate criterion value</returns>
        ICriterion AsEqCriterion(T value);

        /// <summary>
        /// Get composed value of "Is greater than or equal..." criterion
        /// </summary>
        /// <param name="value">Base value</param>
        /// <returns>NHibernate criterion value</returns>
        ICriterion AsGeCriterion(T value);

        /// <summary>
        /// Get composed value of "Is greater than..." criterion
        /// </summary>
        /// <param name="value">Base value</param>
        /// <returns>NHibernate criterion value</returns>
        ICriterion AsGtCriterion(T value);

        /// <summary>
        /// Get composed value of "Is in..." criterion
        /// </summary>
        /// <param name="value">Collecion of base values</param>
        /// <returns>NHibernate criterion value</returns>
        ICriterion AsInCriterion(ICollection<T> value);

        /// <summary>
        /// Get composed value of "Is insensitive like..." criterion
        /// </summary>
        /// <param name="value">Base value</param>
        /// <returns>NHibernate criterion value</returns>
        ICriterion AsInsensitiveLikeCriterion(T value);

        /// <summary>
        /// Get composed value of "Is empty..." criterion
        /// </summary>
        /// <returns>NHibernate criterion value</returns>
        ICriterion AsIsEmptyCriterion();

        /// <summary>
        /// Get composed value of "Is not empty..." criterion
        /// </summary>
        /// <returns>NHibernate criterion value</returns>
        ICriterion AsIsNotEmptyCriterion();

        /// <summary>
        /// Get composed value of "Is null..." criterion
        /// </summary>
        /// <returns>NHibernate criterion value</returns>
        ICriterion AsIsNullCriterion();

        /// <summary>
        /// Get composed value of "Is not null..." criterion
        /// </summary>
        /// <returns>NHibernate criterion value</returns>
        ICriterion AsIsNotNullCriterion();

        /// <summary>
        /// Get composed value of "Is lower than or equal..." criterion
        /// </summary>
        /// <param name="value">Base value</param>
        /// <returns>NHibernate criterion value</returns>
        ICriterion AsLeCriterion(T value);

        /// <summary>
        /// Get composed value of "Is like..." criterion
        /// </summary>
        /// <param name="value">Base value</param>
        /// <returns>NHibernate criterion value</returns>
        ICriterion AsLikeCriterion(T value);

        /// <summary>
        /// Get composed value of "Is lower than..." criterion
        /// </summary>
        /// <param name="value">Base value</param>
        /// <returns>NHibernate criterion value</returns>
        ICriterion AsLtCriterion(T value);

        /// <summary>
        /// Get composed value of "Is not equal..." criterion
        /// </summary>
        /// <param name="value">Base value</param>
        /// <returns>NHibernate criterion value</returns>
        ICriterion AsNotEqCriterion(T value);

        /// <summary>
        /// Set "Is between ... and ..." criterion value
        /// </summary>
        /// <param name="beginValue">Begin valueof between range</param>
        /// <param name="endValue">End value of between range</param>
        ICriterionJoin<T> SetBetween(T beginValue, T endValue);

        /// <summary>
        /// Set "Is equal..." criterion value
        /// </summary>
        /// <param name="value">Base value</param>
        ICriterionJoin<T> SetEq(T value);

        /// <summary>
        /// Set "Is greater than or equal..." criterion value
        /// </summary>
        /// <param name="value">Base value</param>  
        ICriterionJoin<T> SetGe(T value);

        /// <summary>
        /// Set "Is greater than..." criterion value
        /// </summary>
        /// <param name="value">Base value</param>  
        ICriterionJoin<T> SetGt(T value);

        /// <summary>
        /// Set "Is insensitive like..." criterion value
        /// </summary>
        /// <param name="value">Base value</param>  
        ICriterionJoin<T> SetInsentiveLike(T value);

        /// <summary>
        /// Set "Is empty..." criterion value
        /// </summary>
        ICriterionJoin<T> SetIsEmpty();

        /// <summary>
        /// Set "Is not empty..." criterion value
        /// </summary>
        ICriterionJoin<T> SetIsNotEmpty();

        /// <summary>
        /// Set "Is not null..." criterion value
        /// </summary>
        ICriterionJoin<T> SetIsNotNull();

        /// <summary>
        /// Set "Is null..." criterion value
        /// </summary>
        ICriterionJoin<T> SetIsNull();

        /// <summary>
        /// Set "Is lower than or equal..." criterion value
        /// </summary>
        /// <param name="value">Base value</param>  
        ICriterionJoin<T> SetLe(T value);

        /// <summary>
        /// Set "Is like..." criterion value
        /// </summary>
        /// <param name="value">Base value</param>  
        ICriterionJoin<T> SetLike(T value);

        /// <summary>
        /// Set "Is lower than..." criterion value
        /// </summary>
        /// <param name="value">Base value</param>  
        ICriterionJoin<T> SetLt(T value);

        /// <summary>
        /// Set "Is not equal..." criterion value
        /// </summary>
        /// <param name="value">Base value</param>  
        ICriterionJoin<T> SetNotEq(T value);

        /// <summary>
        /// Set "Is in..." criterion value
        /// </summary>
        /// <param name="values">Base values</param>  
        ICriterionJoin<T> SetIn(ICollection<T> values);

        /// <summary>
        /// Set "Is NOT in..." criterion value
        /// </summary>
        /// <param name="values">Base values</param>  
        ICriterionJoin<T> SetNotIn(ICollection<T> values);

        /// <summary>
        /// Set "Is equal..." subquery criterion value
        /// </summary>
        /// <param name="subqueryProjection">Generic-projected detached criteria</param>
        ICriterionJoin<T> SetEq(GenericSubqueryProjection<T> subqueryProjection);

        /// <summary>
        /// Set "All are equal..." subquery criterion value
        /// </summary>
        /// <param name="subqueryProjection">Generic-projected detached criteria</param>
        ICriterionJoin<T> SetEqAll(GenericSubqueryProjection<T> subqueryProjection);

        /// <summary>
        /// Set "Is greater that or even..." subquery criterion value
        /// </summary>
        /// <param name="subqueryProjection">Generic-projected detached criteria</param>
        ICriterionJoin<T> SetGe(GenericSubqueryProjection<T> subqueryProjection);

        /// <summary>
        /// Set "All are greater than or even..." subquery criterion value
        /// </summary>
        /// <param name="subqueryProjection">Generic-projected detached criteria</param>
        ICriterionJoin<T> SetGeAll(GenericSubqueryProjection<T> subqueryProjection);

        /// <summary>
        /// Set "Some are greater or even..." subquery criterion value
        /// </summary>
        /// <param name="subqueryProjection">Generic-projected detached criteria</param>
        ICriterionJoin<T> SetGeSome(GenericSubqueryProjection<T> subqueryProjection);

        /// <summary>
        /// Set "Is greater than..." subquery criterion value
        /// </summary>
        /// <param name="subqueryProjection">Generic-projected detached criteria</param>
        ICriterionJoin<T> SetGt(GenericSubqueryProjection<T> subqueryProjection);

        /// <summary>
        /// Set "All are greater than..." subquery criterion value
        /// </summary>
        /// <param name="subqueryProjection">Generic-projected detached criteria</param>
        ICriterionJoin<T> SetGtAll(GenericSubqueryProjection<T> subqueryProjection);

        /// <summary>
        /// Set "Some are greater than..." subquery criterion value
        /// </summary>
        /// <param name="subqueryProjection">Generic-projected detached criteria</param>
        ICriterionJoin<T> SetGtSome(GenericSubqueryProjection<T> subqueryProjection);

        /// <summary>
        /// Set "Is in..." subquery criterion value
        /// </summary>
        /// <param name="subqueryProjection">Generic-projected detached criteria</param>
        ICriterionJoin<T> SetIn(GenericSubqueryProjection<T> subqueryProjection);

        /// <summary>
        /// Set "Is lower than or even..." subquery criterion value
        /// </summary>
        /// <param name="subqueryProjection">Generic-projected detached criteria</param>
        ICriterionJoin<T> SetLe(GenericSubqueryProjection<T> subqueryProjection);

        /// <summary>
        /// Set "All are lower than or even..." subquery criterion value
        /// </summary>
        /// <param name="subqueryProjection">Generic-projected detached criteria</param>
        ICriterionJoin<T> SetLeAll(GenericSubqueryProjection<T> subqueryProjection);

        /// <summary>
        /// Set "Some are lower than or even..." subquery criterion value
        /// </summary>
        /// <param name="subqueryProjection">Generic-projected detached criteria</param>
        ICriterionJoin<T> SetLeSome(GenericSubqueryProjection<T> subqueryProjection);

        /// <summary>
        /// Set "Is lower than..." subquery criterion value
        /// </summary>
        /// <param name="subqueryProjection">Generic-projected detached criteria</param>
        ICriterionJoin<T> SetLt(GenericSubqueryProjection<T> subqueryProjection);

        /// <summary>
        /// Set "All are lower than..." subquery criterion value
        /// </summary>
        /// <param name="subqueryProjection">Generic-projected detached criteria</param>
        ICriterionJoin<T> SetLtAll(GenericSubqueryProjection<T> subqueryProjection);

        /// <summary>
        /// Set "Some are lower than..." subquery criterion value
        /// </summary>
        /// <param name="subqueryProjection">Generic-projected detached criteria</param>
        ICriterionJoin<T> SetLtSome(GenericSubqueryProjection<T> subqueryProjection);

        /// <summary>
        /// Set "Is not equal..." subquery criterion value
        /// </summary>
        /// <param name="subqueryProjection">Generic-projected detached criteria</param>
        ICriterionJoin<T> SetNe(GenericSubqueryProjection<T> subqueryProjection);

        /// <summary>
        /// Set "Is not in..." subquery criterion value
        /// </summary>
        /// <param name="subqueryProjection">Generic-projected detached criteria</param>
        ICriterionJoin<T> SetNotIn(GenericSubqueryProjection<T> subqueryProjection);

        /// <summary>
        /// Set "Is equal..." subquery criterion value
        /// </summary>
        /// <param name="subqueryProjection">Generic-projected detached criteria</param>
        ICriterionJoin<T> SetEq(GenericSubqueryProjection<object> subqueryProjection);

        /// <summary>
        /// Set "All are equal..." subquery criterion value
        /// </summary>
        /// <param name="subqueryProjection">Generic-projected detached criteria</param>
        ICriterionJoin<T> SetEqAll(GenericSubqueryProjection<object> subqueryProjection);

        /// <summary>
        /// Set "Is greater that or even..." subquery criterion value
        /// </summary>
        /// <param name="subqueryProjection">Generic-projected detached criteria</param>
        ICriterionJoin<T> SetGe(GenericSubqueryProjection<object> subqueryProjection);

        /// <summary>
        /// Set "All are greater than or even..." subquery criterion value
        /// </summary>
        /// <param name="subqueryProjection">Generic-projected detached criteria</param>
        ICriterionJoin<T> SetGeAll(GenericSubqueryProjection<object> subqueryProjection);

        /// <summary>
        /// Set "Some are greater or even..." subquery criterion value
        /// </summary>
        /// <param name="subqueryProjection">Generic-projected detached criteria</param>
        ICriterionJoin<T> SetGeSome(GenericSubqueryProjection<object> subqueryProjection);

        /// <summary>
        /// Set "Is greater than..." subquery criterion value
        /// </summary>
        /// <param name="subqueryProjection">Generic-projected detached criteria</param>
        ICriterionJoin<T> SetGt(GenericSubqueryProjection<object> subqueryProjection);

        /// <summary>
        /// Set "All are greater than..." subquery criterion value
        /// </summary>
        /// <param name="subqueryProjection">Generic-projected detached criteria</param>
        ICriterionJoin<T> SetGtAll(GenericSubqueryProjection<object> subqueryProjection);

        /// <summary>
        /// Set "Some are greater than..." subquery criterion value
        /// </summary>
        /// <param name="subqueryProjection">Generic-projected detached criteria</param>
        ICriterionJoin<T> SetGtSome(GenericSubqueryProjection<object> subqueryProjection);

        /// <summary>
        /// Set "Is in..." subquery criterion value
        /// </summary>
        /// <param name="subqueryProjection">Generic-projected detached criteria</param>
        ICriterionJoin<T> SetIn(GenericSubqueryProjection<object> subqueryProjection);

        /// <summary>
        /// Set "Is lower than or even..." subquery criterion value
        /// </summary>
        /// <param name="subqueryProjection">Generic-projected detached criteria</param>
        ICriterionJoin<T> SetLe(GenericSubqueryProjection<object> subqueryProjection);

        /// <summary>
        /// Set "All are lower than or even..." subquery criterion value
        /// </summary>
        /// <param name="subqueryProjection">Generic-projected detached criteria</param>
        ICriterionJoin<T> SetLeAll(GenericSubqueryProjection<object> subqueryProjection);

        /// <summary>
        /// Set "Some are lower than or even..." subquery criterion value
        /// </summary>
        /// <param name="subqueryProjection">Generic-projected detached criteria</param>
        ICriterionJoin<T> SetLeSome(GenericSubqueryProjection<object> subqueryProjection);

        /// <summary>
        /// Set "Is lower than..." subquery criterion value
        /// </summary>
        /// <param name="subqueryProjection">Generic-projected detached criteria</param>
        ICriterionJoin<T> SetLt(GenericSubqueryProjection<object> subqueryProjection);

        /// <summary>
        /// Set "All are lower than..." subquery criterion value
        /// </summary>
        /// <param name="subqueryProjection">Generic-projected detached criteria</param>
        ICriterionJoin<T> SetLtAll(GenericSubqueryProjection<object> subqueryProjection);

        /// <summary>
        /// Set "Some are lower than..." subquery criterion value
        /// </summary>
        /// <param name="subqueryProjection">Generic-projected detached criteria</param>
        ICriterionJoin<T> SetLtSome(GenericSubqueryProjection<object> subqueryProjection);

        /// <summary>
        /// Set "Is not equal..." subquery criterion value
        /// </summary>
        /// <param name="subqueryProjection">Generic-projected detached criteria</param>
        ICriterionJoin<T> SetNe(GenericSubqueryProjection<object> subqueryProjection);

        /// <summary>
        /// Set "Is not in..." subquery criterion value
        /// </summary>
        /// <param name="subqueryProjection">Generic-projected detached criteria</param>
        ICriterionJoin<T> SetNotIn(GenericSubqueryProjection<object> subqueryProjection);        



        /// <summary>
        /// Creates subquery from this property which from which contains actual 
        /// recorder criterions which have been set to this point.
        /// </summary>
        /// <returns>NHibernate detached criteria as a projected subquery criterion</returns>
        GenericSubqueryProjection<T> RecordedProjection { get; }

        /// <summary>
        /// Creates subquery from this property which from which contains actual 
        /// recorder criterions which have been set to this point.
        /// </summary>
        /// <returns>NHibernate detached criteria as a projected subquery criterion</returns>
        GenericSubqueryProjection<T> RecordedProjectionMax { get; }
    
        /// <summary>
        /// Creates subquery from this property which from which contains actual 
        /// recorder criterions which have been set to this point.
        /// </summary>
        /// <returns>NHibernate detached criteria as a projected subquery criterion</returns>
        GenericSubqueryProjection<T> RecordedProjectionMin { get; }

        /// <summary>
        /// Creates subquery from this property which from which contains actual 
        /// recorder criterions which have been set to this point.
        /// </summary>
        /// <returns>NHibernate detached criteria as a projected subquery criterion</returns>
        GenericSubqueryProjection<T> RecordedProjectionAvg { get; }


        /// <summary>
        /// Creates subquery from this property which from which contains actual 
        /// recorder criterions which have been set to this point.
        /// </summary>
        /// <returns>NHibernate detached criteria as a projected subquery criterion</returns>
        GenericSubqueryProjection<T> RecordedProjectionSum { get; } 

    }
}
